package com.qike.duola.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.qike.duola.domain.*;
import com.qike.duola.dto.*;
import com.qike.duola.enums.*;
import com.qike.duola.mapper.*;
import com.qike.duola.service.ApprovalService;
import com.qike.duola.service.DuolaProjectService;
import com.qike.duola.service.DuolaQuoteService;
import com.qike.duola.utils.StringUtil;
import com.qike.duola.vo.*;
import org.apache.ibatis.jdbc.Null;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Eric.zhou
 * @Date: 2020/9/2 15:10
 */
@Service
public class DuolaQuoteServiceImpl implements DuolaQuoteService {


    private static final Logger logger = LoggerFactory.getLogger(DuolaQuoteServiceImpl.class);

    @Autowired
    private DuolaQuoteMapper duolaQuoteMapper;

    @Autowired
    private DuolaQuotePayMapper duolaQuotePayMapper;
    @Autowired
    private DuolaProjectMapper duolaProjectMapper;

    @Autowired
    private DuolaCustomerMapper duolaCustomerMapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private ApprovalService approvalService;

    /**
     * 添加报价单
     *
     * @param quoteAddDto
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED)
    public void quoteAdd(QuoteAddDto quoteAddDto) throws Exception {
        //添加报价单主题
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"添加报价单"+ JSON.toJSON(quoteAddDto));
        approvalService.findProcess(ApprovalOrderTypeEnums.QUOTE.getEcode());
        DuolaQuote quote = new DuolaQuote();
        quote.setAddTime(LocalDateTime.now());
        quote.setAddUid(userId);
        quote.setStatus(StatusEnums.NO.getEcode());
        quote.setContractName(quoteAddDto.getContractName());
        quote.setContractPhone(quoteAddDto.getContractPhone());
        quote.setTitle(quoteAddDto.getTitle());
        quote.setQuoteNum(quoteAddDto.getQuoteNum());
        quote.setCustomerId(quoteAddDto.getCustomerUid());
        quote.setProjectId(quoteAddDto.getProjectId());
        quote.setSaleId(quoteAddDto.getSaleId());
        quote.setRemark(quoteAddDto.getRemark());
        quote.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        quote.setIsOther(quoteAddDto.getIsOther());
        quote.setStartTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(quoteAddDto.getStartTime()), ZoneId.systemDefault()));
        quote.setEndTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(quoteAddDto.getEndTime()), ZoneId.systemDefault()));
       quote.setPercentage(new Double(70));
       quote.setDays(90);
        duolaQuoteMapper.insertSelective(quote);
        // 添加结算方式
        for (PayTypeDto payTypeDto : quoteAddDto.getPayTypeList()) {
            for (PayTypeGoodsDto payTypeGoodsDto : payTypeDto.getList()) {
                DuolaQuotePay duolaQuotePay = new DuolaQuotePay();
                duolaQuotePay.setGoodsName(payTypeGoodsDto.getGoodsName());
                duolaQuotePay.setGoodsId(payTypeGoodsDto.getGoodsId());
                duolaQuotePay.setGoodsPrice(payTypeGoodsDto.getGoodsPrice());
                duolaQuotePay.setAddTime(LocalDateTime.now());
                duolaQuotePay.setQuoteId(quote.getId());
                duolaQuotePay.setStatus(StatusEnums.NO.getEcode());
                duolaQuotePay.setPayType(payTypeDto.getPayType());
                duolaQuotePayMapper.insertSelective(duolaQuotePay);
            }
        }
        //todo 发起审批
        try {
            approvalService.startApproval(userId,quote.getId(), ApprovalOrderTypeEnums.QUOTE.getEcode());
        } catch (Exception e) {
            throw  e;
        }

    }

    /**
     * 报价单列表
     *
     * @param quoteListDto
     * @return
     */
    @Override
    public QuoteListVo quoteList(QuoteListDto quoteListDto) {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"报价单列表"+ JSON.toJSON(quoteListDto));
        QuoteListVo vo = new QuoteListVo();
        List<QuoteList> list = new ArrayList<>();

        DuolaQuoteExample example = new DuolaQuoteExample();
        DuolaQuoteExample.Criteria criteria = example.createCriteria();
        criteria.andStatusEqualTo(StatusEnums.NO.getEcode());
        //客户查询
        if (quoteListDto.getCustomerId() != null) {
            criteria.andCustomerIdEqualTo(quoteListDto.getCustomerId());
        }
        //联系人查询
        if (!StringUtils.isEmpty(quoteListDto.getContractName())) {
            criteria.andContractNameEqualTo(quoteListDto.getContractName());
        }
        //联系电话查询
        if (!StringUtils.isEmpty(quoteListDto.getPhone())) {
            criteria.andContractPhoneEqualTo(quoteListDto.getPhone());
        }
        //工程查询
        if (quoteListDto.getProjectId() != null) {
            criteria.andProjectIdEqualTo(quoteListDto.getProjectId());
        }
        //工程查询
        if (quoteListDto.getSaleId() != null) {
            criteria.andSaleIdEqualTo(quoteListDto.getSaleId());
        }
        //查询所有客户
        Map<Integer, String> customerMap = new HashMap<>();
        List<DuolaCustomer> duolaCustomers = duolaCustomerMapper.selectByExample(new DuolaCustomerExample());
        for (DuolaCustomer duolaCustomer : duolaCustomers) {
            customerMap.put(duolaCustomer.getId(), duolaCustomer.getCustomerName());
        }
        //查询所有工程
        Map<Integer, String> ProjectMap = new HashMap<>();
        List<DuolaProject> duolaProjects = duolaProjectMapper.selectByExample(new DuolaProjectExample());
        for (DuolaProject duolaProject : duolaProjects) {
            ProjectMap.put(duolaProject.getId(), duolaProject.getProjectName());
        }
        //查询所有人员
        Map<Long, String> userMap = new HashMap<>();
        List<SysUser> sysUsers = sysUserMapper.selectByExample(new SysUserExample());
        for (SysUser sysUser : sysUsers) {
            userMap.put(sysUser.getId(), sysUser.getNickname());
        }
        example.setOrderByClause("add_time desc");
        Page page = PageHelper.startPage(quoteListDto.getStartPage(), quoteListDto.getPageSize());
        List<DuolaQuote> duolaQuotes = duolaQuoteMapper.selectByExample(example);
        for (DuolaQuote duolaQuote : duolaQuotes) {
            QuoteList quoteList = new QuoteList();
            quoteList.setTitle(duolaQuote.getTitle());
            quoteList.setAddTime(duolaQuote.getAddTime().toString());
            quoteList.setContractId(duolaQuote.getContractId());
            quoteList.setCustomerName(duolaQuote.getContractName());
            quoteList.setPhone(duolaQuote.getContractPhone());
            String s = ProjectMap.get(duolaQuote.getProjectId());
            quoteList.setProjectName(s);
            quoteList.setQuoteNum(duolaQuote.getQuoteNum());
            String s1 = customerMap.get(duolaQuote.getCustomerId());
            quoteList.setCustomerName(s1);
            quoteList.setContactName(duolaQuote.getContractName());
            quoteList.setTime(duolaQuote.getStartTime().toString() + "-" + duolaQuote.getEndTime().toString());
            String s2 = userMap.get(duolaQuote.getSaleId());
            quoteList.setSaleName(s2);
            quoteList.setId(duolaQuote.getId());
            quoteList.setRemark(duolaQuote.getRemark());
            quoteList.setExamineStatus(duolaQuote.getExamineStatus());
            quoteList.setExamineStatusStr(ExamineEnums.statOf(duolaQuote.getExamineStatus()).getEmsg());

            list.add(quoteList);
        }
        vo.setList(list);
        vo.setTotal(page.getTotal());
        return vo;
    }

    /**
     * 编辑报价单
     *
     * @param quoteAddDto
     */
    @Override
    public void quoteEdit(QuoteEditDto quoteAddDto) throws Exception {
        //添加报价单主题
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"编辑报价单"+ JSON.toJSON(quoteAddDto));
        approvalService.findProcess(ApprovalOrderTypeEnums.QUOTE.getEcode());
        DuolaQuote quote = duolaQuoteMapper.selectByPrimaryKey(quoteAddDto.getId());
        if (quote==null){
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        if (!quote.getExamineStatus().equals(ExamineEnums.EXAMINE_REFUSE.getEcode())){
            throw new Exception(ErrorEnums.ERROR_UPDATE.getEmsg());
        }
        quote.setContractName(quoteAddDto.getContractName());
        quote.setContractPhone(quoteAddDto.getContractPhone());
        quote.setTitle(quoteAddDto.getTitle());
        quote.setQuoteNum(quoteAddDto.getQuoteNum());
        quote.setProjectId(quoteAddDto.getProjectId());
        quote.setSaleId(quoteAddDto.getSaleId());
        quote.setRemark(quoteAddDto.getRemark());
        quote.setExamineStatus(ExamineEnums.EXAMINE_ING.getEcode());
        quote.setIsOther(quoteAddDto.getIsOther());
        quote.setStartTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(quoteAddDto.getStartTime()), ZoneId.systemDefault()));
        quote.setEndTime(LocalDateTime.ofInstant(Instant.ofEpochMilli(quoteAddDto.getEndTime()), ZoneId.systemDefault()));
        duolaQuoteMapper.updateByPrimaryKey(quote);

        DuolaQuotePayExample quotePayExample = new DuolaQuotePayExample();
        quotePayExample.createCriteria().andQuoteIdEqualTo(quoteAddDto.getId());
        List<DuolaQuotePay> duolaQuotePays = duolaQuotePayMapper.selectByExample(quotePayExample);
        for (DuolaQuotePay duolaQuotePay : duolaQuotePays) {
            duolaQuotePayMapper.deleteByPrimaryKey(duolaQuotePay.getId());
        }
        // 添加结算方式
        for (PayTypeDto payTypeDto : quoteAddDto.getPayTypeList()) {
            for (PayTypeGoodsDto payTypeGoodsDto : payTypeDto.getList()) {
                DuolaQuotePay duolaQuotePay = new DuolaQuotePay();
                duolaQuotePay.setGoodsName(payTypeGoodsDto.getGoodsName());
                duolaQuotePay.setGoodsPrice(payTypeGoodsDto.getGoodsPrice());
                duolaQuotePay.setAddTime(LocalDateTime.now());
                duolaQuotePay.setQuoteId(quote.getId());
                duolaQuotePay.setStatus(StatusEnums.NO.getEcode());
                duolaQuotePay.setPayType(payTypeDto.getPayType());
                duolaQuotePayMapper.insertSelective(duolaQuotePay);
            }
        }

    }

    /**
     * 删除报价单
     *
     * @param id
     */
    @Override
    public void quoteDel(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        logger.info(userId+"删除报价单"+ JSON.toJSON(id));
        DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(id);
        if (duolaQuote==null){
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        //报价单只有在审核拒绝 或 审核完成后未绑定合同 可以删除
        if (!duolaQuote.getExamineStatus().equals(ExamineEnums.EXAMINE_REFUSE.getEcode())||(!duolaQuote.getExamineStatus().equals(ExamineEnums.EXAMINE_SUCCESS.getEcode())&&duolaQuote.getContractId()==null)){
            duolaQuote.setStatus(StatusEnums.YES.getEcode());
            duolaQuoteMapper.updateByPrimaryKey(duolaQuote);
        }
    }

    /**
     * 通过工程选择对应的报价单列表
     *
     * @param projectId
     * @return
     */
    @Override
    public List<EnumList> quoteListByProjectId(Integer projectId) {
        DuolaQuoteExample example = new DuolaQuoteExample();
        example.createCriteria().andProjectIdEqualTo(projectId).andExamineStatusEqualTo(ExamineEnums.EXAMINE_SUCCESS.getEcode()).andStatusEqualTo(StatusEnums.NO.getEcode());
        List<DuolaQuote> duolaQuotes = duolaQuoteMapper.selectByExample(example);
        List<EnumList> lists = new ArrayList<>();
        for (DuolaQuote duolaQuote : duolaQuotes) {
            EnumList enumList = new EnumList();
            enumList.setKey(duolaQuote.getId());
            enumList.setValue(duolaQuote.getQuoteNum());
            lists.add(enumList);
        }
        return lists;
    }

    /**
     * 通过工程选择对应的报价单
     *
     * @param quoteId
     * @return
     */
    @Override
    public List<EnumList> payListByQuoteId(Integer quoteId) {
        Map<Integer,Integer> map = new HashMap<>();
        List<EnumList> lists = new ArrayList<>();
        DuolaQuotePayExample example = new DuolaQuotePayExample();
        example.createCriteria().andQuoteIdEqualTo(quoteId);
        List<DuolaQuotePay> duolaQuotePays = duolaQuotePayMapper.selectByExample(example);
        for (DuolaQuotePay duolaQuotePay : duolaQuotePays) {
            map.put(duolaQuotePay.getPayType(),duolaQuotePay.getQuoteId());
        }
        Map<Integer,DuolaQuote>  quoteMap = new HashMap<>();
        List<DuolaQuote> duolaQuotes = duolaQuoteMapper.selectByExample(new DuolaQuoteExample());
        for (DuolaQuote duolaQuote : duolaQuotes) {
            quoteMap.put(duolaQuote.getId(),duolaQuote);
        }
        for (Integer integer : map.keySet()) {
            EnumList enumList = new EnumList();
            enumList.setKey(integer);
            if (integer.equals(PayTypeEnums.MONTH_PERCENTAGE.getEcode())){
                DuolaQuote duolaQuote = quoteMap.get(map.get(integer));
                enumList.setValue(StringUtil.contractString(duolaQuote.getPercentage(),duolaQuote.getDays()));
            }else {
                enumList.setValue(PayTypeEnums.statOf(integer).getEmsg());
            }

            lists.add(enumList);
        }
        return lists;
    }

    /**
     * 通过报价单id列出所有商品价格及结算方式
     *
     * @param quoteId
     * @return
     */
    @Override
    public List<PayGoodsListByQuoteIdVo> payGoodsListByQuoteId(Integer quoteId) {
        List<PayGoodsListByQuoteIdVo> list = new ArrayList<>();
        Map<Integer,List<PayGoodsListByQuoteId>> goodsMap = new HashMap<>();
        //根据报价单id查询商品
        DuolaQuotePayExample example = new DuolaQuotePayExample();
        example.createCriteria().andQuoteIdEqualTo(quoteId);
        List<DuolaQuotePay> duolaQuotePays = duolaQuotePayMapper.selectByExample(example);
        for (DuolaQuotePay duolaQuotePay : duolaQuotePays) {
            PayGoodsListByQuoteId payGoodsListByQuoteId = new PayGoodsListByQuoteId();
            payGoodsListByQuoteId.setId(duolaQuotePay.getId());
            payGoodsListByQuoteId.setGoodsId(duolaQuotePay.getGoodsId());
            payGoodsListByQuoteId.setGoodsName(duolaQuotePay.getGoodsName());
            payGoodsListByQuoteId.setGoodsPrice(duolaQuotePay.getGoodsPrice());
            List<PayGoodsListByQuoteId> payGoodsListByQuoteIds = goodsMap.get(duolaQuotePay.getPayType());
            if (payGoodsListByQuoteIds==null){
                payGoodsListByQuoteIds = new ArrayList<>();
            }
            payGoodsListByQuoteIds.add(payGoodsListByQuoteId);
            goodsMap.put(duolaQuotePay.getPayType(),payGoodsListByQuoteIds);
        }
        DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(quoteId);
        for (Map.Entry<Integer, List<PayGoodsListByQuoteId>> integerListEntry : goodsMap.entrySet()) {
            PayGoodsListByQuoteIdVo vo = new PayGoodsListByQuoteIdVo();
            vo.setPayType(integerListEntry.getKey());
            if(integerListEntry.getKey().equals(PayTypeEnums.MONTH_PERCENTAGE.getEcode())){
                vo.setPayTypeName(StringUtil.contractString(duolaQuote.getPercentage(),duolaQuote.getDays()));
            }else {
                vo.setPayTypeName(PayTypeEnums.statOf(integerListEntry.getKey()).getEmsg());
            }

            vo.setGoodsList(integerListEntry.getValue());
            list.add(vo);
        }
        return list;
    }

    /**
     * 通过客户id获取所有已审批通过的工程
     *
     * @param uid
     * @return
     */
    @Override
    public List<DuolaProject> payExaminProjectByUid(Integer uid,String projectName) {
        DuolaProjectExample example = new DuolaProjectExample();
        DuolaProjectExample.Criteria criteria = example.createCriteria();
        criteria.andCustomerIdEqualTo(uid);
        if (!StringUtils.isEmpty(projectName)){
            criteria.andProjectNameLike(projectName);
        }
        criteria.andExamineStatusEqualTo(ExamineEnums.EXAMINE_SUCCESS.getEcode());
        List<DuolaProject> duolaProjects = duolaProjectMapper.selectByExample(example);
        return duolaProjects;
    }

    /**
     * 通过id获取报价单
     *
     * @param id
     * @return
     */
    @Override
    public QuoteList quoteById(Integer id) throws Exception {
        Long userId = (Long) SecurityUtils.getSubject().getPrincipal();
        DuolaQuote duolaQuote = duolaQuoteMapper.selectByPrimaryKey(id);
        if (duolaQuote==null){
            throw new Exception(ErrorEnums.ERROR_DATA.getEmsg());
        }
        //查询所有客户
        Map<Integer, String> customerMap = new HashMap<>();
        List<DuolaCustomer> duolaCustomers = duolaCustomerMapper.selectByExample(new DuolaCustomerExample());
        for (DuolaCustomer duolaCustomer : duolaCustomers) {
            customerMap.put(duolaCustomer.getId(), duolaCustomer.getCustomerName());
        }
        //查询所有工程
        Map<Integer, String> ProjectMap = new HashMap<>();
        List<DuolaProject> duolaProjects = duolaProjectMapper.selectByExample(new DuolaProjectExample());
        for (DuolaProject duolaProject : duolaProjects) {
            ProjectMap.put(duolaProject.getId(), duolaProject.getProjectName());
        }
        //查询所有人员
        Map<Long, String> userMap = new HashMap<>();
        List<SysUser> sysUsers = sysUserMapper.selectByExample(new SysUserExample());
        for (SysUser sysUser : sysUsers) {
            userMap.put(sysUser.getId(), sysUser.getNickname());
        }
        QuoteList quoteList = new QuoteList();
        quoteList.setTitle(duolaQuote.getTitle());
        quoteList.setAddTime(duolaQuote.getAddTime().toString());
        quoteList.setContractId(duolaQuote.getContractId());
        quoteList.setCustomerName(duolaQuote.getContractName());
        quoteList.setPhone(duolaQuote.getContractPhone());
        String s = ProjectMap.get(duolaQuote.getProjectId());
        quoteList.setProjectName(s);
        quoteList.setQuoteNum(duolaQuote.getQuoteNum());
        String s1 = customerMap.get(duolaQuote.getCustomerId());
        quoteList.setCustomerName(s1);
        quoteList.setContactName(duolaQuote.getContractName());
        quoteList.setTime(duolaQuote.getStartTime().toString() + "-" + duolaQuote.getEndTime().toString());
        String s2 = userMap.get(duolaQuote.getSaleId());
        quoteList.setSaleName(s2);
        quoteList.setId(duolaQuote.getId());
        quoteList.setRemark(duolaQuote.getRemark());
        quoteList.setExamineStatus(duolaQuote.getExamineStatus());
        quoteList.setExamineStatusStr(ExamineEnums.statOf(duolaQuote.getExamineStatus()).getEmsg());
        return quoteList;
    }
}

